package io.kiki.sba.registry.server.clientInterface.providedata;

import io.kiki.sba.registry.common.model.constants.ValueConstants;
import io.kiki.sba.registry.common.model.metaserver.ProvideData;
import io.kiki.sba.registry.server.clientInterface.bootstrap.Config;
import io.kiki.sba.registry.server.clientInterface.push.ChangeProcessor;
import io.kiki.sba.registry.server.clientInterface.push.FirePushService;
import io.kiki.sba.registry.server.clientInterface.push.PushEfficiencyImproveConfig;
import io.kiki.sba.registry.server.clientInterface.push.PushProcessor;
import io.kiki.sba.registry.server.shared.providedata.AbstractFetchSystemPropertyService;
import io.kiki.sba.registry.server.shared.providedata.SystemDataStorage;
import io.kiki.sba.registry.util.JsonUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;


public class FetchPushEfficiencyConfigService extends AbstractFetchSystemPropertyService<FetchPushEfficiencyConfigService.SwitchStorage> {

    private static final Logger logger = LoggerFactory.getLogger(FetchPushEfficiencyConfigService.class);
    @Autowired
    private Config config;

    @Autowired
    private ChangeProcessor changeProcessor;
    @Autowired
    private PushProcessor pushProcessor;

    @Autowired
    private FirePushService firePushService;

    public FetchPushEfficiencyConfigService() {
        super(ValueConstants.CHANGE_PUSH_TASK_DELAY_CONFIG_DATA_ID, new SwitchStorage(INIT_VERSION, new PushEfficiencyImproveConfig()));
    }

    @Override
    protected int getSystemPropertyIntervalMillis() {
        return config.getSystemPropertyIntervalMillis();
    }

    @Override
    protected boolean doProcess(SwitchStorage expect, ProvideData data) {
        final String configString = ProvideData.toString(data);

        PushEfficiencyImproveConfig pushEfficiencyImproveConfig = new PushEfficiencyImproveConfig();
        if (StringUtils.isBlank(configString)) {
            return true;
        }
        try {
            pushEfficiencyImproveConfig = JsonUtils.read(configString, PushEfficiencyImproveConfig.class);
        } catch (Throwable e) {
            logger.error("Decode PushEfficiencyImproveConfig failed", e);
            return false;
        }
        if (pushEfficiencyImproveConfig == null || !pushEfficiencyImproveConfig.validate()) {
            logger.error("Fetch PushEfficiencyImproveConfig invalid, value={}", pushEfficiencyImproveConfig);
            return false;
        }
        pushEfficiencyImproveConfig.setSessionServerConfig(config);
        if (!pushEfficiencyImproveConfig.inIpZoneSBF()) {
            return false;
        }

        SwitchStorage update = new SwitchStorage(data.getVersion(), pushEfficiencyImproveConfig);
        if (!compareAndSet(expect, update)) {
            return false;
        }
        changeProcessor.setWorkDelayTime(pushEfficiencyImproveConfig);
        pushProcessor.setPushTaskDelayTime(pushEfficiencyImproveConfig);
        if (firePushService.getRegProcessor() != null) {
            firePushService.getRegProcessor().setWorkDelayTime(pushEfficiencyImproveConfig);
        }
        logger.info("Fetch PushEfficiencyImproveConfig success, prev={}, current={}", expect.pushEfficiencyImproveConfig, pushEfficiencyImproveConfig);
        return true;
    }


    public FetchPushEfficiencyConfigService setChangeProcessor(ChangeProcessor changeProcessor) {
        this.changeProcessor = changeProcessor;
        return this;
    }


    public FetchPushEfficiencyConfigService setPushProcessor(PushProcessor pushProcessor) {
        this.pushProcessor = pushProcessor;
        return this;
    }


    public FetchPushEfficiencyConfigService setFirePushService(FirePushService firePushService) {
        this.firePushService = firePushService;
        return this;
    }


    public FetchPushEfficiencyConfigService setSessionServerConfig(Config config) {
        this.config = config;
        return this;
    }

    protected static class SwitchStorage extends SystemDataStorage {
        protected final PushEfficiencyImproveConfig pushEfficiencyImproveConfig;

        public SwitchStorage(long version, PushEfficiencyImproveConfig pushEfficiencyImproveConfig) {
            super(version);
            this.pushEfficiencyImproveConfig = pushEfficiencyImproveConfig;
        }
    }
}
